package model.trader;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * This class wraps instructions for the trade strategy to convert to real trades.
 * What we want to do is describe the shape of our demand. For example we might want 
 * to buy 50 at the current market price, but none if the market price is 20 dollars
 * higher. 
 * 
 * @author andy
 *
 */
public class TradeInstruction {

	public static class IndicativePricePair{
		private double price;
		private int trade;
		
		public IndicativePricePair(double price, int trade){
			this.price=price;
			this.trade=trade;
		}
		
		public double getPrice() {
			return price;
		}
	
		public int getTrade() {
			return trade;
		}
	}
	
	private int numberToTrade;
	private double holdPrice;
	private int assetRef;
	private List<IndicativePricePair> additional = new ArrayList<IndicativePricePair>();
	
	public int getAsset() {
		return assetRef;
	}
	
	public void setAsset(int assetRef) {
		this.assetRef = assetRef;
	}
	
	public int getNumberToTrade() {
		return numberToTrade;
	}
	public void setNumberToTrade(int numberToTrade) {
		this.numberToTrade = numberToTrade;
	}
	
	//AMLOW: order these.. at the moment it is just assumed that they'll be.
	public List<IndicativePricePair> getAdditional() {
		return additional;
	}
	
	public void addIndication(double price,int trade){
		additional.add(new IndicativePricePair(price,trade));
	}
	
	public double getHoldPrice(){
		
		if(additional.size()>0){
			for(IndicativePricePair pair:additional){
				if(numberToTrade<=0&&pair.trade>=0){
					return pair.price;
				}
				if(numberToTrade>=0&&pair.trade<=0){
					return pair.price;
				}
			}
			return additional.get(additional.size()-1).price;
		}else{
			//market order.
			if(numberToTrade<0){
				return 0;
			}
			return Integer.MAX_VALUE;
		}
	}
	
	
	public void draw(double marketPrice){
		if(numberToTrade>0){
			int stepSize=Math.max(1,(numberToTrade)/50);
			System.out.println("-----Buying-----");
			double holdPrice=getHoldPrice();
			for(double i=holdPrice;i>0&&i>marketPrice;i-=.02*holdPrice){
				double tradeQuantity= getBuyTradeAtPrice(i);
				System.out.print(""+NumberFormat.getCurrencyInstance().format(i)+"	");
				for(int step=0;step<tradeQuantity;step+=stepSize){
					System.out.print(" ");
				}
				System.out.print("X");
				System.out.println();
			}
			System.out.println();
			System.out.println("-----Thats it-----");
		}
	}
	
	private double getBuyTradeAtPrice(double price){
		int belowTrade=0;
		int belowTradePrice=0;
		for(IndicativePricePair pair:additional){
			if(pair.getPrice()>=price){
				if(belowTrade==0){
					return pair.getTrade();
				}else{
					int tradeDiff=belowTrade-pair.getTrade();
					double priceDiff=pair.getPrice()-belowTradePrice;
					return belowTrade - (tradeDiff*(price-belowTradePrice)/priceDiff);
				}
			}
		}
		return 0;
	}
	
}
